import os
import sys
import logging
import neuro.config as config

logging.basicConfig(format=config.log_format, level=config.log_level, stream=sys.stdout)

def load(version="dev"):
	'''
	Switch NIT version at runtime ::
		
		#!/usr/bin/env python
		import neuro
		neuro.load("1.5.0")

	NIT version root is defined as:
	  1. Value stored in $NIT_VERSIONS environment variable
	  2. Three levels up from this module

	:param version: NIT version string e.g. "1.3.1"
	:type version: str
	'''
	nitVersions = os.getenv("NIT_VERSIONS")
	
	## --- default is three dirs up from current file
	if(nitVersions == None or nitVersions.strip() == ""):
		nitVersions = os.path.join(__file__, "..", "..", "..")
	
	nitVersions = os.path.expanduser(nitVersions)
	nitVersions = os.path.abspath(nitVersions)

	## --- build the version path
	versionPath = os.path.join(nitVersions, version)
	neuroDir = os.path.join(versionPath, "neuro")

	## --- try to open the neuro package initializer
	try:
		h = open(os.path.join(neuroDir, "__init__.py"))
	except IOError, ioe:
		if(ioe.errno == 2):
			raise LoaderException(LoaderException.NO_DIR, neuroDir)
		elif(ioe.errno == 13):
			raise LoaderException(LoaderException.NO_ACCESS, neuroDir)
		else:
			raise LoaderException(None, neuroDir)
	except:
		raise LoaderException(None, neuroDir)

	h.close()

	## --- find and remove any other NIT versions from sys.path
	for i in range(len(sys.path) - 1):
		initFile = os.path.join(sys.path[i], "neuro", "__init__.py")
		try:
			h = open(initFile)
			del sys.path[i]
			h.close()
		except:
			pass

	## --- add the desired NIT version to the front of sys.path however after
	## --- position 0 which is typically going to be the called script
	sys.path.insert(1, versionPath)

	## --- remove the currently registered neuro module
	del sys.modules["neuro"]

class LoaderException(Exception):
	'''
	NIT loader exception
	'''
	NO_DIR = 0
	NO_ACCESS = 1

	def __init__(self, type, versionDir):
		'''
		Constructor

		:param type: Exception type
		:type type: int
		:param versionDir: str Version directory name
		'''
		self._type = type
		self._versionDir = versionDir

	def getType(self):
		'''
		Get exception type

		:rtype: int
		'''
		return self._type

	def getVersionDir(self):
		'''
		Get version directory

		:rtype: str
		'''
		return self._versionDir

	def getMessage(self):
		'''
		Get exception message

		:rtype: str
		'''
		if(self._type == LoaderException.NO_DIR):
			return "Unable to load version (no package init): " + self._versionDir
		elif(self._type == LoaderException.NO_ACCESS):
			return "Unable to load version (insufficient access privileges): " + self._versionDir
		else:
			return "Unknown loader exception: " + self._versionDir

	def __str__(self):
		'''
		To string
		'''
		return self.getMessage()
